package vaccine.appointment.system.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vaccine.appointment.system.common.enums.DelFlgEnum;
import vaccine.appointment.system.common.errorcode.CommonErrorCode;
import vaccine.appointment.system.common.exception.CommonException;
import vaccine.appointment.system.common.utils.EncryptionAndDecryptionUtil;
import vaccine.appointment.system.common.utils.JWTUtil;
import vaccine.appointment.system.person.dataobject.Person;
import vaccine.appointment.system.person.mapper.PersonMapper;
import vaccine.appointment.system.user.dataobject.User;
import vaccine.appointment.system.user.enums.IdentityInfoEnum;
import vaccine.appointment.system.user.errorcode.UserErrorCode;
import vaccine.appointment.system.user.exception.UserException;
import vaccine.appointment.system.user.mapper.UserMapper;
import vaccine.appointment.system.user.service.UserService;
import vaccine.appointment.system.user.vo.ChangePasswordRequest;
import vaccine.appointment.system.user.vo.CreateStaffRequest;
import vaccine.appointment.system.user.vo.LoginResponse;
import vaccine.appointment.system.user.vo.RegisterRequest;
import vaccine.appointment.system.user.vo.StaffInfoVO;
import vaccine.appointment.system.vaccinationsite.dataobject.VaccinationSite;
import vaccine.appointment.system.vaccinationsite.mapper.VaccinationSiteMapper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PersonMapper personMapper;

    @Autowired
    private VaccinationSiteMapper vaccinationSiteMapper;

    /**
     * 用户登录
     * @param userName 用户名（账号）
     * @param password 密码
     * @return 登录响应（包含JWT token）
     */
    @Override
    public LoginResponse login(String userName, String password) {
        // 1. 根据用户名查询用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account", userName);
        queryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        User user = userMapper.selectOne(queryWrapper);

        // 2. 判断用户是否存在
        if (user == null) {
            throw new UserException(UserErrorCode.USER_NOT_EXISTS);
        }

        // 3. 验证密码
        boolean passwordMatch = EncryptionAndDecryptionUtil.decryptByDigester(password, user.getPassword());
        if (!passwordMatch) {
            throw new UserException(UserErrorCode.PASSWORD_ERROR);
        }

        // 4. 生成JWT token
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getId());
        claims.put("personId", user.getPersonId());
        claims.put("identityInfo", user.getIdentityInfo());
        claims.put("account", user.getAccount());

        String token = JWTUtil.genJwt(claims);

        // 5. 返回登录响应
        return new LoginResponse(token);
    }

    /**
     * 用户注册
     * @param registerRequest 注册请求信息
     * @return 注册是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean register(RegisterRequest registerRequest) {
        // 1. 参数校验
        if (registerRequest == null) {
            throw new UserException(UserErrorCode.INVALID_PARAMETER);
        }

        // 2. 检查用户名是否已存在
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("account", registerRequest.getAccount());
        userQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        User existingUser = userMapper.selectOne(userQueryWrapper);
        if (existingUser != null) {
            throw new UserException(UserErrorCode.USER_ALREADY_EXISTS);
        }

        // 3. 检查身份证号是否已存在
        QueryWrapper<Person> personQueryWrapper = new QueryWrapper<>();
        personQueryWrapper.eq("id_num", registerRequest.getIdNum());
        personQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Person existingPerson = personMapper.selectOne(personQueryWrapper);
        if (existingPerson != null) {
            throw new UserException(UserErrorCode.ID_NUM_ALREADY_EXISTS);
        }

        // 4. 创建Person记录
        Person person = new Person();
        person.setName(registerRequest.getName());
        person.setAge(registerRequest.getAge());
        person.setIdNum(registerRequest.getIdNum());
        person.setDelFlg(DelFlgEnum.NOT_DELETED.getCode());

        int personResult = personMapper.insert(person);
        if (personResult <= 0) {
            throw new UserException(UserErrorCode.REGISTER_FAILED);
        }

        // 5. 创建User记录
        User user = new User();
        user.setAccount(registerRequest.getAccount());
        // 加密密码
        String encryptedPassword = EncryptionAndDecryptionUtil.encryptByDigester(registerRequest.getPassword());
        user.setPassword(encryptedPassword);
        user.setEmail(registerRequest.getEmail());
        user.setPersonId(person.getId());
        user.setIdentityInfo(IdentityInfoEnum.NORMAL_USER.getCode());
        user.setDelFlg(DelFlgEnum.NOT_DELETED.getCode());

        int userResult = userMapper.insert(user);
        if (userResult <= 0) {
            throw new UserException(UserErrorCode.REGISTER_FAILED);
        }

        return true;
    }

    /**
     * 修改密码
     * @param userId 用户ID
     * @param request 修改密码请求
     * @return 是否成功
     */
    @Override
    public Boolean changePassword(Integer userId, ChangePasswordRequest request) {
        // 1. 查询用户
        User user = userMapper.selectById(userId);
        if (user == null || user.getDelFlg().equals(DelFlgEnum.DELETED.getCode())) {
            throw new UserException(UserErrorCode.USER_NOT_EXISTS);
        }

        // 2. 验证旧密码
        boolean passwordMatch = EncryptionAndDecryptionUtil.decryptByDigester(request.getOldPassword(), user.getPassword());
        if (!passwordMatch) {
            throw new UserException(UserErrorCode.PASSWORD_ERROR);
        }

        // 3. 加密新密码
        String encryptedNewPassword = EncryptionAndDecryptionUtil.encryptByDigester(request.getNewPassword());

        // 4. 更新密码
        user.setPassword(encryptedNewPassword);
        int result = userMapper.updateById(user);

        return result > 0;
    }

    /**
     * 创建工作人员账号（管理员功能）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createStaff(CreateStaffRequest request) {
        // 1. 验证身份信息（只能创建接种点管理员或超级管理员）
        if (!request.getIdentityInfo().equals(IdentityInfoEnum.HOSPITAL_ADMIN.getCode())
            && !request.getIdentityInfo().equals(IdentityInfoEnum.SUPER_ADMIN.getCode())) {
            throw new CommonException(CommonErrorCode.INVALID_PARAMETER);
        }

        // 2. 如果是接种点管理员，必须指定接种点
        if (request.getIdentityInfo().equals(IdentityInfoEnum.HOSPITAL_ADMIN.getCode())) {
            if (request.getVaccinationSiteId() == null) {
                throw new CommonException(CommonErrorCode.INVALID_PARAMETER);
            }
            // 验证接种点是否存在
            VaccinationSite site = vaccinationSiteMapper.selectById(request.getVaccinationSiteId());
            if (site == null || site.getDelFlg().equals(DelFlgEnum.DELETED.getCode())) {
                throw new CommonException(CommonErrorCode.NOT_FOUND);
            }
        }

        // 3. 检查用户名是否已存在
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("account", request.getAccount());
        userQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        User existingUser = userMapper.selectOne(userQueryWrapper);
        if (existingUser != null) {
            throw new UserException(UserErrorCode.USER_ALREADY_EXISTS);
        }

        // 4. 检查身份证号是否已存在
        QueryWrapper<Person> personQueryWrapper = new QueryWrapper<>();
        personQueryWrapper.eq("id_num", request.getIdNum());
        personQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
        Person existingPerson = personMapper.selectOne(personQueryWrapper);
        if (existingPerson != null) {
            throw new UserException(UserErrorCode.ID_NUM_ALREADY_EXISTS);
        }

        // 5. 创建Person记录
        Person person = new Person();
        person.setName(request.getName());
        person.setAge(request.getAge());
        person.setIdNum(request.getIdNum());
        person.setDelFlg(DelFlgEnum.NOT_DELETED.getCode());
        personMapper.insert(person);

        // 6. 创建User记录
        User user = new User();
        user.setAccount(request.getAccount());
        String encryptedPassword = EncryptionAndDecryptionUtil.encryptByDigester(request.getPassword());
        user.setPassword(encryptedPassword);
        user.setEmail(request.getEmail());
        user.setPersonId(person.getId());
        user.setIdentityInfo(request.getIdentityInfo());
        user.setVaccinationSiteId(request.getVaccinationSiteId());
        user.setDelFlg(DelFlgEnum.NOT_DELETED.getCode());
        userMapper.insert(user);

        return true;
    }

    /**
     * 查询工作人员列表（管理员功能）
     */
    @Override
    public Page<StaffInfoVO> getStaffList(Integer identityInfo, Integer pageNum, Integer pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

        // 只查询管理员账号（非普通用户）
        queryWrapper.ne("identity_info", IdentityInfoEnum.NORMAL_USER.getCode());
        queryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());

        // 身份信息筛选
        if (identityInfo != null) {
            queryWrapper.eq("identity_info", identityInfo);
        }

        queryWrapper.orderByDesc("id");

        Page<User> userPage = userMapper.selectPage(page, queryWrapper);

        // 组装VO
        Page<StaffInfoVO> voPage = new Page<>(pageNum, pageSize);
        voPage.setTotal(userPage.getTotal());

        List<StaffInfoVO> voList = new ArrayList<>();
        for (User user : userPage.getRecords()) {
            StaffInfoVO vo = new StaffInfoVO();
            vo.setUserId(user.getId());
            vo.setAccount(user.getAccount());
            vo.setEmail(user.getEmail());
            vo.setIdentityInfo(user.getIdentityInfo());
            vo.setIdentityInfoDesc(IdentityInfoEnum.forName(
                IdentityInfoEnum.values()[user.getIdentityInfo()].name()).getDescription());
            vo.setVaccinationSiteId(user.getVaccinationSiteId());

            // 查询Person信息
            Person person = personMapper.selectById(user.getPersonId());
            if (person != null) {
                vo.setName(person.getName());
                vo.setAge(person.getAge());
                vo.setIdNum(person.getIdNum());
            }

            // 查询接种点信息
            if (user.getVaccinationSiteId() != null) {
                VaccinationSite site = vaccinationSiteMapper.selectById(user.getVaccinationSiteId());
                if (site != null) {
                    vo.setVaccinationSiteName(site.getName());
                }
            }

            voList.add(vo);
        }
        voPage.setRecords(voList);

        return voPage;
    }

    /**
     * 删除工作人员账号（管理员功能）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteStaff(Integer staffId) {
        User user = userMapper.selectById(staffId);
        if (user == null || user.getDelFlg().equals(DelFlgEnum.DELETED.getCode())) {
            throw new CommonException(CommonErrorCode.NOT_FOUND);
        }

        // 不能删除普通用户
        if (user.getIdentityInfo().equals(IdentityInfoEnum.NORMAL_USER.getCode())) {
            throw new CommonException(CommonErrorCode.FORBIDDEN);
        }

        user.setDelFlg(DelFlgEnum.DELETED.getCode());
        userMapper.updateById(user);
        return true;
    }

    /**
     * 重置工作人员密码（管理员功能）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean resetStaffPassword(Integer staffId, String newPassword) {
        User user = userMapper.selectById(staffId);
        if (user == null || user.getDelFlg().equals(DelFlgEnum.DELETED.getCode())) {
            throw new CommonException(CommonErrorCode.NOT_FOUND);
        }

        // 不能重置普通用户密码
        if (user.getIdentityInfo().equals(IdentityInfoEnum.NORMAL_USER.getCode())) {
            throw new CommonException(CommonErrorCode.FORBIDDEN);
        }

        String encryptedPassword = EncryptionAndDecryptionUtil.encryptByDigester(newPassword);
        user.setPassword(encryptedPassword);
        userMapper.updateById(user);
        return true;
    }
}
